package com.dream.app.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dream.app.cache.AppOrgCache;
import com.dream.app.service.OrgService;
import com.dream.dao.base.AppOrgDAO;
import com.dream.model.app.AppAbstractUser;
import com.dream.model.app.AppOrg;
import com.dream.model.app.AppPosition;
import com.dream.model.app.AppPosition.PositionType;
import com.dream.vo.base.TreeNodeVO;
import com.google.common.collect.Lists;

@Service("orgService")
public class OrgServiceImpl implements OrgService {

	@Autowired
	private AppOrgDAO appOrgDAO;
	
	@Autowired
	private AppOrgCache appOrgCache;
	
	@Override
	@Transactional
	public AppOrg getOrgTree(Long checkedId) {
		
		AppOrg root = appOrgDAO.getRoot();
		if(checkedId.compareTo(0L)<0){
			root.setChecked(true);
		}
		loopChildren(root,checkedId);
		return root;
	}
	
	@Transactional
	private void loopChildren(final AppOrg root,final Long checkedId){
		
		if(root != null && root.getId().equals(checkedId)){
			root.setChecked(true);
		}
		List<AppOrg> children = appOrgDAO.getChildren(root.getId());
		root.setChildren(children);
		if(CollectionUtils.isNotEmpty(children)){
			for(AppOrg item : children){
				loopChildren(item,checkedId);
			}
		}
	}


	@Override
	@Transactional
	public void update(TreeNodeVO vo, AppAbstractUser user) {
		if(vo.getId() == null ){
			
			AppOrg  newItem = new 	AppOrg();
			newItem.setId(vo.getId());
			newItem.setName(vo.getName());
			newItem.setParentId(vo.getParentId());
			AppOrg parent = appOrgDAO.selectById(vo.getParentId());
			newItem.setLevel(parent.getLevel()+1);
			
			newItem.setCreateTime(new Date());
			newItem.setCreateUser(user.getId());
			appOrgDAO.save(newItem);
			
		}else{
			AppOrg me = appOrgDAO.selectById(vo.getId());
			me.setName(vo.getName());
			me.setUpdateTime(new Date());
			me.setUpdateUser(user.getId());
			appOrgDAO.saveOrUpdate(me);
		}
		appOrgCache.reload();
	}

	@Override
	@Transactional
	public void delete(Long id, AppAbstractUser user) {
		
		AppOrg me = appOrgDAO.selectById(id);
		me.setDeleted(true);
		appOrgDAO.saveOrUpdate(me);
		appOrgCache.reload();
	}
	
	@Override
	@Transactional
	public List<Long> getLeafOrgs(String first, String second) {
		
		List<Long> li = Lists.newArrayList();
		if(StringUtils.isNotBlank(second)){
			li.add(Long.parseLong(second));
		}else if(StringUtils.isNotBlank(first)){
			li.add(Long.parseLong(first));
			List<AppOrg> children = appOrgCache.getChildren(Long.parseLong(first));
			if(CollectionUtils.isNotEmpty(children)){
				for(AppOrg item : children){
					li.add(item.getId());
				}
			}
		}
		
		return li;
		
	}
	
	@Override
	@Transactional
	public List<AppOrg> getFirstOrg() {
		
		AppOrg root = appOrgCache.getRoot();
		return appOrgCache.getChildren(root.getId());
	}

	@Override
	@Transactional
	public List<AppOrg> getFirstOrgOfMine(AppAbstractUser user) {
		AppPosition position = user.getPosition();
		if(position == null){
			return getFirstOrg();
		}
		
		if(PositionType.manager.equals(position.getType())){
			if(user.getOrgId() == null){
				return getFirstOrg();
			}
			return judgeLever1(user);
		}
		
		if(PositionType.staff.equals(position.getType())){
			if(user.getOrgId() != null){
				return judgeLever1(user);
			}
		}
		return Lists.newArrayList();
	}

	@Override
	@Transactional
	public List<AppOrg> getChildrenOfMine(Long parentId,AppAbstractUser user) {
		
		AppPosition position = user.getPosition();
		if(position == null){
			return appOrgCache.getChildren(parentId);
		}
		
		if(PositionType.manager.equals(position.getType())){
			if(user.getOrgId() == null){
				return appOrgCache.getChildren(parentId);
			}
			
			return judgeLever2(parentId,user);
		}
		
		if(PositionType.staff.equals(position.getType())){
			if(user.getOrgId() != null){
				return judgeLever2(parentId,user);
			}
		}
		
		
		return Lists.newArrayList();
		
	}
	
	@Transactional
	private List<AppOrg> judgeLever1(AppAbstractUser user) {
		
		AppOrg org = appOrgCache.getOrg(user.getOrgId());
		if(org == null ){return Lists.newArrayList();}
		
		//总部
		if(org.getLevel().equals(0)){
			return getFirstOrg();
		}
		
		//大区
		if(org.getLevel().equals(1)){
			return  Lists.newArrayList(org);
		}
		
		//办事处
		if(org.getLevel().equals(2)){
			return  Lists.newArrayList(appOrgCache.getOrg(org.getParentId()));
		}
		
		return Lists.newArrayList();
	}

	@Transactional
	private List<AppOrg> judgeLever2(Long parentId,AppAbstractUser user) {
		
		AppOrg org = appOrgCache.getOrg(user.getOrgId());
		if(org == null ){return Lists.newArrayList();}
		
		//总部
		if(org.getLevel().equals(0)){
			return appOrgCache.getChildren(parentId);
		}
		
		//大区
		if(org.getLevel().equals(1)){
			return  appOrgCache.getChildren(org.getId());
		}
		
		//办事处
		if(org.getLevel().equals(2)){
			return  Lists.newArrayList(org);
		}
		
		return Lists.newArrayList();
	}

	@Override
	@Transactional
	public List<AppOrg> getParent(Long id) {
		
		List<AppOrg> li = Lists.newArrayList();
		while(id.compareTo(0L)>0){
			AppOrg me = getDetail(id);
			li.add(me);
			id = me.getParentId();
		}
		return li;
	}

	@Override
	@Transactional
	public AppOrg getDetail(Long id) {
		return appOrgDAO.selectById(id);
	}

	@Override
	@Transactional
	public List<AppOrg> getChild(Long id) {
		return appOrgDAO.getChildren(id);
	}
	
	
	
	

}
